#include "user.h"
#include "../std/systemcall.h"
#include "../std/file_common.h"
#include "../std/errno.h"

User currentUser;

void changeCurrentUser(User * user);
void getUserRoot(User * user);

void loadUserWorkspace(User * user){
	
	mknode(user->path,775,DIRECTORY_TYPE);
	
	lchown(user->path,user->name,user->group);
	
	changeCurrentUser(user);
	
	chdir(user->path);
	
}

int getUserParam(char * ret, int length){
	
	char c = '\0';
	int i = 0;
	while ((c = getchar()) != '\n' && i < length-1) {
	    ret[i++] = c;
	}
	ret[i] = '\0';
	
	if( c == '\n'){
		return i;
	}
	
	while (getchar() != '\n');
	
	return i;
	
}

int loadUser(User * user, char * name){
	UsersInfo users;
	
	int fd=open(USERS_FILE,O_RD);
	if(fd == -1){	  
		return -1;
	}
	
	
	__read(fd,(char *)&users,sizeof(users));
	
	int i;
	for(i=0;i<users.cant;i++){
		if(strcmp(users.list[i].name, name) == 0){			
			strcpy(user->name, users.list[i].name);		
			strcpy(user->pass, users.list[i].pass);
			strcpy(user->group, users.list[i].group);
			strcpy(user->path, users.list[i].path);	
			return 1;
		}
	}
	
	return 0;	
}

int logout(int argc, char* argv[]){
	
  	login();
}	

void login(void){
	
	char name[NAME_MAX_LENGTH];
	User user;
	
	printk("\x1B[33mUsername: \x1B[0m");
	getUserParam(name,NAME_MAX_LENGTH);
	
	int correctName =loadUser(&user, name);
	if(!correctName){
		printk("%s : Invalid user\n", name);
		login();
		return;
	}
	
	char pass[PASS_LENGTH];
	int times=0;
	int correctPass=0;
	do{	
		printk("\x1B[33mPassword: \x1B[0m");
		getUserParam(pass, PASS_LENGTH);
		times++;
		correctPass = !strcmp(user.pass, pass);
	}while(!correctPass && times<3);
	
	if(!correctPass){		
		printk("Invalid loggin\n");
		login();
		return;		
	}

	loadUserWorkspace(&user);
	
	return;	
	
}

int newUser(int argc, char* argv[]){
	
	if(strcmp(currentUser.name, "system") != 0){
		printf("newuser: Permission denied\n");
		return -1;		
	}
	
	char name[NAME_MAX_LENGTH];
	User user;
	

	printk("\x1B[33mNew Username(Max length %d): \x1B[0m", NAME_MAX_LENGTH);
	
	getUserParam(name,NAME_MAX_LENGTH);
	
	if(strlen(name) < 1){
		printk("Invalid Username\n", name);
		return -1;
	}
	
	int correctName =loadUser(&user, name);
	if(correctName){
		printk("%s : User already exists\n", name);
		return -1;
	}
		
	char pass1[PASS_LENGTH];
	printk("\x1B[33mPassword(Max length %d): \x1B[0m", PASS_LENGTH);
	getUserParam(pass1, PASS_LENGTH);
	
	char pass2[PASS_LENGTH];	
	printk("\x1B[33mPassword again: \x1B[0m");
	getUserParam(pass2, PASS_LENGTH);
	
	if(strcmp(pass1, pass2)!=0){
		printk("passwd: diferent Password\n");
		return -1;		
	}
	

	if(!addUser(name, pass1))
		printk("newuser: User created\n");
		printk("User name: %s\n", name);
		printk("Password: %s\n", pass1);
	
	return 0;
	
}

int group(int argc, char* argv[]){
		
	char pass[PASS_LENGTH];
	char group[NAME_MAX_LENGTH];
	printf("\x1B[33mActual password: \x1B[0m");
	getUserParam(pass, PASS_LENGTH);
	
	if(strcmp(currentUser.pass, pass) != 0){
		printf("passwd: Invalid Password\n");
		return -1;
	}
	
	printf("\x1B[33mNew group(Max length %d): \x1B[0m", NAME_MAX_LENGTH);
	getUserParam(group, NAME_MAX_LENGTH);
		
	strcpy(currentUser.group, group);
	
	
	UsersInfo users;	
	int fd=open(USERS_FILE, O_CREATE);
	if(fd == -1){	  
	 	printf("group: error:%s\n", strerror(errno)); 
		return -1;
	}
	
	__read(fd,(char *)&users,sizeof(users));

	int i;
	for(i=0;i<users.cant;i++){
		if(strcmp(users.list[i].name, currentUser.name) == 0){
			strcpy(users.list[i].group, group);
		}
	}
	
	fd=open(USERS_FILE,O_CREATE);
	__write(fd,(char *)&users,sizeof(users));
	
	
	printf("group: Group changed\n");
	return 0;
	
}

int passwd(int argc, char* argv[]){
		
	char pass[PASS_LENGTH];
	printk("\x1B[33mActual password: \x1B[0m");
	getUserParam(pass, PASS_LENGTH);
	
	if(strcmp(currentUser.pass, pass) != 0){
		printk("passwd: Invalid Password\n");
		return -1;
	}
	
	printk("\x1B[33mNew password(Max length %d): \x1B[0m", PASS_LENGTH);
	getUserParam(pass, PASS_LENGTH);
	
	char pass2[PASS_LENGTH];	
	printk("\x1B[33mNew password again: \x1B[0m");
	getUserParam(pass2, PASS_LENGTH);
	
	if(strcmp(pass, pass2)!=0){
		printk("passwd: diferent Password\n");
		return -1;		
	}
	
	strcpy(currentUser.pass, pass);	
	
	UsersInfo users;	
	int fd=open(USERS_FILE, 0);
	if(fd == -1){	  
	 	printf("passwd: error:%s\n", strerror(errno)); 
		return -1;
	}
	
	__read(fd,(char *)&users,sizeof(users));

	int i;
	for(i=0;i<users.cant;i++){
		if(strcmp(users.list[i].name, currentUser.name) == 0){
			strcpy(users.list[i].pass, pass);
		}
	}
	
	fd=open(USERS_FILE,O_CREATE);
	__write(fd,(char *)&users,sizeof(users));
	
	
	printk("passwd: Password changed\n");
	
	return 0;
	
}

int addUser(char * name, char * pass){
	
	UsersInfo users;
	
	int fd=open(USERS_FILE,O_CREATE);
	if(fd == -1){	  
	 	printf("adduser: error:%s\n", strerror(errno)); 
		return -1;
	}
	
	__read(fd,(char *)&users,sizeof(users));
	
	users.cant=users.cant+1;	
	if(users.cant == MAX_USERS){
		printk("Maximum amount of users reached!\n");
		return -1;	
	}
	
	char path[NAME_MAX_LENGTH+1];
	strcpy(path, "/");
	strcpy(path+1, name);
	
	strcpy(users.list[users.cant-1].name, name);
	strcpy(users.list[users.cant-1].group, name);
	strcpy(users.list[users.cant-1].pass, pass);
	strcpy(users.list[users.cant-1].path, path);
	
	fd=open(USERS_FILE,O_CREATE);
	__write(fd,(char *)&users,sizeof(users));
		
	return 0;
	
}

void changeCurrentUser(User * user){
	
	setuName(user->name);
	setgName(user->group);
	
	strcpy(currentUser.name, user->name);
	strcpy(currentUser.group, user->group);
	strcpy(currentUser.path, user->path);
	strcpy(currentUser.pass, user->pass);
	setUserName(currentUser.name);
	
}


void initUsersFile(){
	
	User root;
	getUserRoot(&root);
	
	UsersInfo users;
	users.cant=1;
	
	strcpy(users.list[0].name, root.name);
	strcpy(users.list[0].group, root.group);
	strcpy(users.list[0].pass, root.pass);
	strcpy(users.list[0].path, root.path);
	
	int fd=open(USERS_FILE,O_CREATE | O_EXCL);
	
	if(fd==-1){
		return;
	}
	__write(fd,(char *)&users,sizeof(users));
			
	close(fd);
	
	chmod(USERS_FILE, 777);
	
	return;
	
}

void getUserRoot(User * user){
	
	strcpy(user->name, SYSTEM_NAME);
	strcpy(user->group, SYSTEM_GROUP);
	strcpy(user->pass, SYSTEM_PASS);
	strcpy(user->path, SYSTEM_PATH);
	
}
